/*
 * Controller.h
 *
 *  Created on: Jun 14, 2011
 *      Author: rishirajbheda
 */

#ifndef MANIFOLD_CAFFDRAM_CONTROLLER_H_
#define MANIFOLD_CAFFDRAM_CONTROLLER_H_

#include "Channel.h"
#include "Dsettings.h"
#include "Dreq.h"

#include "kernel/component-decl.h"
//#include "simple-cache/cache_messages.h"
#include "mcp-cache/coh_mem_req.h"

#include <map>

/*
 *
 */
namespace manifold {
namespace caffdram {


class Controller : public manifold::kernel::Component {
public:
	enum {OUT=0};
	enum {IN=0};

	Controller(int nid, const Dsettings&, bool st_resp=false);
	~Controller();

	int get_nid() { return m_nid; }

	void handle_request(int, manifold::mcp_cache_namespace::Coh_mem_req* req);

        void print_config(std::ostream&);
        void print_stats(std::ostream&);

#ifdef CAFFDRAM_TEST
public:
#else
private:
#endif
	unsigned long int processRequest (unsigned long int reqAddr, unsigned long int currentTime);

	int m_nid; //node id
	const bool m_send_st_response; //send response for stores
	Dsettings* dramSetting;
	Channel** myChannel;

	//for stats
	struct Req_info {
	    Req_info(int t, int oid, int sid, uint64_t a) : type(t), org_id(oid), src_id(sid), addr(a) {}
	    int type; //ld or st
	    int org_id; //originator id
	    int src_id; //source id; could be different from originator id, e.g., when it's from an LLS cache
	    uint64_t addr;
	};

	std::map<int, int> m_ld_misses; //number of ld misses per source
	std::map<int, int> m_stores;
	std::multimap<manifold::kernel::Ticks_t, Req_info> m_req_info; //request info in time order

};

} //namespace caffdram
} //namespace manifold

#endif // MANIFOLD_CAFFDRAM_CONTROLLER_H_
